In programming, an atomic action is one that effectively happens all at once. An atomic action cannot stop in the middle: it either happens completely, or it doesn’t happen at all. No side effects of an atomic action are visible until the action is complete.
以上是关于原子性的操作的相关描述。
在Java中,以下的操作可以认为是原子操作
- 对于引用变量、大多数的原始类型变量的读、写(所有的类型除了
long
和double
)都是原子性的(这个只有才32位的JVM成立) - 所有申明为
volatile
的变量(包括long
和double
变量)的读、写都是原子性的
在Java中,自增、自减操作都不是原子性操作,很容易理解。但是long
和duoble
的读写却不是原子性的问题,却不太好理解。
检验
在32位JVM上,通过两个线程对同一个成员变量进行读写,来测试long
和double
类型变量的读写不是原子性操作。
1 |
|
测试结果为
通过这个例子可以看出
在32位JVM上,对
long
型变量test
的读取或者对long
型变量switchVal
的写入不是原子性的。非原子性的读、写只是造成
long
、double
类型变量的高、低32位数据不一致
这是由于在32位JVM中对64位的数据的读、写分两步,每一步读或者写32位的数据,这样就会造成两个线程对同一个变量的读写出现一个线程写高32位、另一个线程写入低32位数据。这样此变量的数据就出现不一致的情况。这时候volatile
关键字可以防止这种现象发生,因为java的内存模型保证了valotile
修饰的long
、double
变量的读写是原子性的。